package com.tieba.core;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.http.Header;
import org.apache.http.client.ClientProtocolException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import com.alibaba.fastjson.JSON;
import com.tieba.entity.TieBa;
import com.tieba.entity.User;
import com.tieba.util.HttpConnection;
import com.tieba.util.Utils;
import com.tieba.util.XMLBuilder;

public class BaiDuMobSign {

	private static String loginUrl = "http://wappass.baidu.com/passport/login";
	private static String tiebaFavouriteUrl = "http://tieba.baidu.com/f/like/mylike?&pn=";
	private static String tiebaTbs = "http://tieba.baidu.com/dc/common/tbs";
	private static String tiebaSign = "http://c.tieba.baidu.com/c/c/forum/sign";

	private static List<TieBa> waitSignList = new ArrayList<TieBa>();

	public static void main(String[] args) throws Exception {

		List<User> usersList = XMLBuilder.getUsersList();

		for (User user : usersList) {
			if (LoginBaiDu(user)) {
				System.out.println("登录成功");

				if (user.getAutoupdate() == 1) {
					if (autoUpdateFavList(user)) {
						System.out.println("更新关注列表成功");
					} else {
						System.out.println("更新关注列表失败");
					}
				}

				int num = 1;
				while (true) {
					if (num == user.getRetrycount()) {
						System.out.println("已签到" + num + "次，未全部签到完成");
						break;
					}
					if (SignTieba(user)) {
						System.out.println("全部签到完成");
						break;
					} else {
						System.out.println("未全部签到成功，开始第" + (num + 1) + "次签到");
					}
					num++;
				}

			} else {
				System.out.println("登录失败");
			}
			HttpConnection.endHttpClient();
		}

	}

	public static boolean autoUpdateFavList(User user) {
		boolean returnboolean = true;
		try {
			List<TieBa> favXmlTieBaList = XMLBuilder.getTiebaList();
			List<TieBa> favMobTieBaList = getFavouriteTieba();

			for (TieBa xmlTieBa : favXmlTieBaList) {
				if (xmlTieBa.getFalg() == 2) {
					continue;
				}
				boolean needDel = true;
				for (TieBa mobTieBa : favMobTieBaList) {
					if (xmlTieBa.getTname().equals(mobTieBa.getTname())) {
						needDel = false;
					}
				}
				if (needDel) {
					XMLBuilder.delTieBa(xmlTieBa.getId());
				}
			}

			for (TieBa mobTieBa : favMobTieBaList) {
				boolean needAdd = true;
				for (TieBa xmlTieBa : favXmlTieBaList) {
					if (xmlTieBa.getFalg() == 2) {
						continue;
					}
					if (mobTieBa.getTname().equals(xmlTieBa.getTname())) {
						needAdd = false;
					}
				}
				if (needAdd) {
					mobTieBa.setId(UUID.randomUUID().toString());
					mobTieBa.setUser(user.getId());
					mobTieBa.setOrder(0);
					mobTieBa.setFalg(1);
					XMLBuilder.addTieBa(mobTieBa);
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
			returnboolean = false;
		}
		return returnboolean;
	}

	public static boolean SignTieba(User user) throws InterruptedException, UnsupportedEncodingException {

		boolean returnboolean = true;

		if (waitSignList.size() == 0) {
			for (TieBa tieba : XMLBuilder.getTiebaList()) {
				if (tieba.getUser().equals(user.getId())) {
					waitSignList.add(tieba);
				}
			}
		}
		List<TieBa> errorSignList = new ArrayList<TieBa>();

		for (TieBa tieba : waitSignList) {
			System.out.print(tieba.getTname() + ": ");
			String baiDuTbs = HttpConnection.doGet(tiebaTbs, new HashMap<String, String>());
			Map<String, Object> tbsJsonMap = JSON.parseObject(baiDuTbs);
			String tbs = (String) tbsJsonMap.get("tbs");

			String sign = Utils.MD5Encoder("BDUSS=" + user.getBduss() + "fid=" + tieba.getFid() + "kw=" + tieba.getTname() + "tbs=" + tbs + "tiebaclient!!!", "utf-8").toUpperCase();

			Map<String, String> params = new HashMap<String, String>();
			params.put("BDUSS", user.getBduss());
			params.put("fid", String.valueOf(tieba.getFid()));
			params.put("kw", tieba.getTname());
			params.put("tbs", tbs);
			params.put("sign", sign);

			String reString = (String) HttpConnection.doPost(tiebaSign, params).get("content");

			Map<String, Object> jsonMap = JSON.parseObject(reString);

			if (Integer.parseInt(jsonMap.get("error_code").toString()) != 0) {
				errorSignList.add(tieba);
				System.out.println(Utils.URLDecode2String(jsonMap.get("error_msg").toString()));
			} else {
				Map<String, Object> user_info = JSON.parseObject(jsonMap.get("user_info").toString());
				System.out.println("第" + user_info.get("user_sign_rank") + "个签到，连续签到" + user_info.get("cont_sign_num") + "次，总计签到" + user_info.get("total_sign_num") + "次");
			}

			Thread.sleep((long) user.getWaittime() * 1000);
		}
		waitSignList = errorSignList;
		return returnboolean;
	}

	public static boolean LoginBaiDu(User user) throws ClientProtocolException, IOException {

		Map<String, String> params = new HashMap<String, String>();

		params.put("username", user.getUsername());
		params.put("password", user.getPassword());

		try {
			Map<String, Object> result = HttpConnection.doPost(loginUrl, params);
			Header[] headers = (Header[]) result.get("headers");
			String BDUSS = "";
			for (int i = 0; i < headers.length; i++) {
				if (headers[i].getValue().contains("BDUSS")) {
					BDUSS = headers[i].getValue().split("=")[1].split(";")[0];
				}
			}
			user.setBduss(BDUSS);

			if (((String) result.get("content")).contains("verifycode")) {
				System.out.println("需要验证码");
				return false;
			} else if (((String) result.get("content")).contains("error_area")) {
				System.out.println("密码错误");
				return false;
			}
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	public static List<TieBa> getFavouriteTieba() {
		List<TieBa> favouriteTiebaList = new ArrayList<TieBa>();

		int i = 1;
		while (true) {
			String wappage = HttpConnection.doGet(tiebaFavouriteUrl + i, new HashMap<String, String>());
			Document document = Jsoup.parse(wappage);
			Elements likebars = document.select("span[balvid]");
			if (likebars.size() == 0) {
				break;
			}
			for (Element e : likebars) {
				TieBa tieBa = new TieBa();
				tieBa.setFid(Utils.Str2Long(e.attr("balvid")));
				tieBa.setKw(e.attr("balvname"));
				Elements onebars = document.select("a[href=/f?kw=" + e.attr("balvname") + "]");
				tieBa.setTname(onebars.get(0).attr("title"));

				favouriteTiebaList.add(tieBa);
			}
			i++;
		}

		return favouriteTiebaList;
	}
}
